package com.tianyu.inspection.service;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tianyu.inspection.common.Constants;
import com.tianyu.inspection.common.QueryModel;
import com.tianyu.inspection.common.enums.MapLayerTypeEnum;
import com.tianyu.inspection.common.enums.RoState;
import com.tianyu.inspection.common.enums.WebSocketMessageType;
import com.tianyu.inspection.entity.BasicInformation;
import com.tianyu.inspection.entity.SysTypeDef;
import com.tianyu.inspection.entity.model.OperateMo;
import com.tianyu.inspection.entity.model.QueryMo;
import com.tianyu.inspection.entity.vo.ServiceRo;
import com.tianyu.inspection.entity.vo.WebSocketRo;
import com.tianyu.inspection.mapper.BasicInformationMapper;
import com.tianyu.inspection.service.api.IBasicInformationService;
import com.tianyu.inspection.service.api.ISysTypeDefService;
import com.tianyu.inspection.service.websocket.WebSocketService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**********************************
 * @Author YSW
 * @Description 基础信息服务
 * @Date 2023/9/12 - 15:52
 **********************************/

@Slf4j
@Service
public class BasicInformationService implements IBasicInformationService {

    @Resource
    private BasicInformationMapper basicInformationMapper;

    @Resource
    private WebSocketService webSocketService;

    @Resource
    private ISysTypeDefService sysTypeDefService;

    /**
     * 插入一条数据
     *
     * @param basicInformation 实体对象
     * @return 是否操作成功
     */
    @Override
    public boolean insert(BasicInformation basicInformation) {
        return 1 == basicInformationMapper.insert(basicInformation);
    }

    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    public ServiceRo batchInsert(List<BasicInformation> dataList) {
        int count = 0;
        for (BasicInformation basicInformation : dataList) {
            basicInformationMapper.insert(basicInformation);
            count++;
        }
        return new ServiceRo().setData(JSONObject.of("count", count));
    }

    @Override
    public BasicInformation selectById(Integer basicInformationId) {
        return basicInformationMapper.selectById(basicInformationId);
    }

    @Override
    public boolean updateById(BasicInformation basicInformation) {
        return 1 == basicInformationMapper.updateById(basicInformation);
    }

    /**
     * 分页查询
     *
     * @param queryMo 参数模型
     * @return 分页记录对象
     */
    @Override
    public IPage<BasicInformation> searchListPage(JSONObject queryMo) {
        final QueryWrapper<BasicInformation> wrapper = QueryModel.getModelWrapper(BasicInformation.class,
                new QueryWrapper<>(),
                queryMo);
        wrapper.eq("folder", false);
        return QueryModel.getModelPage(wrapper, basicInformationMapper, queryMo);
    }

    @Override
    public IPage<BasicInformation> searchListTypePage(JSONObject queryMo) {
        final Integer projectId = queryMo.getInteger("projectId");
        final Integer typeDefId = queryMo.getInteger("baseTypeId");
        final Set<Integer> typeIds = sysTypeDefService.getMapLayerTypeTreeIds(projectId, typeDefId);
        final QueryWrapper<BasicInformation> wrapper = QueryModel.getModelWrapper(BasicInformation.class,
                new QueryWrapper<>(),
                queryMo);
        wrapper.eq("folder", false);
        wrapper.in("type_def_id", typeIds);
        return QueryModel.getModelPage(wrapper, basicInformationMapper, queryMo);
    }

    @Override
    public ServiceRo getAllData(JSONObject jsonObject) {
        jsonObject.put("pageSize", -1);
        jsonObject.put("pageNum", 1);
        return new ServiceRo().setData(QueryModel.getModelPage(
                BasicInformation.class,
                new QueryWrapper<>(),
                basicInformationMapper,
                jsonObject, "description").getRecords());
    }

    @Override
    public ServiceRo getBasicInformationTypeTree(JSONObject jsonObject) {
        final Integer projectId = jsonObject.getInteger("projectId");
        final Integer typeDefId = jsonObject.getInteger("baseTypeId");
        final Set<Integer> typeIds = sysTypeDefService.getMapLayerTypeTreeIds(projectId, typeDefId);
        if (typeIds.isEmpty()) {
            return new ServiceRo();
        }
        jsonObject.put("pageSize", -1);
        jsonObject.put("pageNum", 1);
        final JSONObject eqParams = jsonObject.getJSONObject("eqParams");
        if (eqParams != null) {
            eqParams.put("projectId", projectId);
        } else {
            jsonObject.put("eqParams", new JSONObject().fluentPut("projectId", projectId));
        }
        final QueryWrapper<BasicInformation> folderQueryWrapper = new QueryWrapper<BasicInformation>()
                .eq("folder", true)
                .eq("project_id", projectId);
        final SysTypeDef sysTypeDef = sysTypeDefService.selectById(typeDefId);
        if (sysTypeDef != null) {
            final Integer mapLayerType = sysTypeDef.getOtherParam().getInteger("mapLayerType");
            folderQueryWrapper.eq("map_layer_type", mapLayerType);
        }
        final List<BasicInformation> folders = QueryModel.getModelPage(
                        folderQueryWrapper,
                        basicInformationMapper,
                        jsonObject)
                .getRecords();
        final QueryWrapper<BasicInformation> wrapper = QueryModel.getModelWrapper(BasicInformation.class,
                new QueryWrapper<>(),
                jsonObject);
        wrapper.eq("folder", false);
        wrapper.in("type_def_id", new ArrayList<>(typeIds));
        final List<BasicInformation> children = QueryModel.getModelPage(wrapper, basicInformationMapper, jsonObject).getRecords();
        Map<Integer, BasicInformation> rootMap = new HashMap<>();
        for (BasicInformation folder : folders) {
            folder.setChildren(new ArrayList<>());
            rootMap.put(folder.getId(), folder);
        }
        for (BasicInformation pipeline : children) {
            final Integer parentId = pipeline.getParentId();
            if (parentId != null) {
                final BasicInformation folder = rootMap.get(parentId);
                if (folder != null) {
                    folder.getChildren().add(pipeline);
                }
            } else {
                rootMap.put(pipeline.getId(), pipeline);
            }
        }
        setChild(folders, rootMap);
        return new ServiceRo().setData(new ArrayList<>(rootMap.values()));
    }

    @Override
    public ServiceRo getBasicInformationTree(JSONObject jsonObject) {
        final Integer projectId = jsonObject.getInteger("projectId");
        jsonObject.put("pageSize", -1);
        jsonObject.put("pageNum", 1);
        final JSONObject eqParams = jsonObject.getJSONObject("eqParams");
        if (eqParams != null) {
            eqParams.put("projectId", projectId);
        } else {
            jsonObject.put("eqParams", new JSONObject().fluentPut("projectId", projectId));
        }
        final List<BasicInformation> folders = QueryModel.getModelPage(
                        new QueryWrapper<BasicInformation>().eq("folder", true).eq("project_id", projectId),
                        basicInformationMapper,
                        jsonObject)
                .getRecords();
        final QueryWrapper<BasicInformation> wrapper = QueryModel.getModelWrapper(BasicInformation.class,
                new QueryWrapper<>(),
                jsonObject, "description");
        wrapper.eq("folder", false);
        final List<BasicInformation> children = QueryModel.getModelPage(wrapper, basicInformationMapper, jsonObject).getRecords();
        Map<Integer, BasicInformation> rootMap = new HashMap<>();
        for (BasicInformation folder : folders) {
            folder.setChildren(new ArrayList<>());
            rootMap.put(folder.getId(), folder);
        }
        for (BasicInformation pipeline : children) {
            final Integer parentId = pipeline.getParentId();
            if (parentId != null) {
                final BasicInformation folder = rootMap.get(parentId);
                if (folder != null) {
                    folder.getChildren().add(pipeline);
                }
            } else {
                rootMap.put(pipeline.getId(), pipeline);
            }
        }
        setChild(folders, rootMap);
        return new ServiceRo().setData(new ArrayList<>(rootMap.values()));
    }

    private void setChild(List<BasicInformation> folders, Map<Integer, BasicInformation> folderMap) {
        for (BasicInformation folder : folders) {
            final Integer parentId = folder.getParentId();
            final Integer folderId = folder.getId();
            if (parentId != null) {
                final List<BasicInformation> childFolders = folderMap.values().stream().filter(value -> folderId.equals(value.getParentId())).collect(Collectors.toList());
                if (childFolders.size() != 0) {
                    setChild(childFolders, folderMap);
                }
                final BasicInformation parentFolder = folderMap.get(parentId);
                if (parentFolder != null) {
                    final List<BasicInformation> children = parentFolder.getChildren();
                    if (children != null) {
                        if (children.stream().noneMatch(basicInformation -> Objects.equals(basicInformation.getId(), folderId))) {
                            children.add(folder);
                            folderMap.remove(folder.getId());
                        }
                    }
                }
            } else {
                final List<BasicInformation> childFolders = folderMap.values().stream().filter(value -> folderId.equals(value.getParentId())).collect(Collectors.toList());
                setChild(childFolders, folderMap);
            }
        }
    }

    @Override
    public ServiceRo getBasicInformationTreeLevel(JSONObject jsonObject) {
        Integer folderId = jsonObject.getInteger("id");
        Integer projectId = jsonObject.getInteger("projectId");
        jsonObject.put("pageSize", -1);
        jsonObject.put("pageNum", 1);
        final JSONObject eqParams = jsonObject.getJSONObject("eqParams");
        final QueryWrapper<BasicInformation> wrapper = new QueryWrapper<>();
        if (eqParams != null) {
            eqParams.put("projectId", projectId);
        } else {
            final JSONObject object = new JSONObject()
                    .fluentPut("projectId", projectId);
            if (folderId == null) {
                wrapper.isNull("parent_id");
            } else {
                object.fluentPut("parentId", folderId);
            }
            jsonObject.put("eqParams", object);
        }
        return new ServiceRo().setData(QueryModel.getModelPage(
                BasicInformation.class,
                wrapper,
                basicInformationMapper,
                jsonObject, "description").getRecords());
    }


    @Override
    public JSONObject kmlJsonLoadPrepare(JSONObject kmlObject, Integer loadType) {
        final JSONObject xml = kmlObject.getJSONObject("kml");
        final JSONObject document = xml.getJSONObject("Document");
        final JSONObject object = JSONObject.parseObject(document.toJSONString());
        AtomicInteger folderCount = new AtomicInteger(0);
        AtomicInteger placemarkCountTotal = new AtomicInteger(0);
        recursionParserObjCount(object, folderCount, placemarkCountTotal, loadType);
        log.info("folderCount: {} ,placemarkCount: {}", folderCount, placemarkCountTotal);
        return JSONObject.of("folderCount", folderCount, "placemarkCountTotal", placemarkCountTotal);
    }


    @Async
    protected void recursionParserObjCount(JSONObject object, AtomicInteger folderCount, AtomicInteger placemarkCount, Integer loadType) {
        final Set<Map.Entry<String, Object>> entries = object.entrySet();
        if (object.containsKey("Folder")) {
            folderCount.incrementAndGet();
        }
        for (Map.Entry<String, Object> entry : entries) {
            final String key = entry.getKey();
            final Object value = entry.getValue();
            if ("Folder".equals(key)) {
                if (value instanceof JSONArray) {
                    for (Object value2 : JSONArray.from(value)) {
                        recursionParserObjCount(JSONObject.from(value2), folderCount, placemarkCount, loadType);
                    }
                    continue;
                }
                if (value instanceof JSONObject) {
                    recursionParserObjCount(JSONObject.from(value), folderCount, placemarkCount, loadType);
                    continue;
                }
            }
            if ("Placemark".equals(key)) {
                if (value instanceof JSONArray) {
                    folderCount.incrementAndGet();
                    final JSONArray placemarks = JSONArray.from(value);
                    for (Object placemark : placemarks) {
                        final JSONObject jsonObject = JSONObject.from(placemark);
                        countPlacemark(jsonObject, placemarkCount, loadType);
                    }
                } else {
                    countPlacemark(JSONObject.from(value), placemarkCount, loadType);
                }
            }
        }
    }


    private void countPlacemark(JSONObject placemark, AtomicInteger placemarkCount, Integer loadType) {
        final JSONObject lineString = placemark.getJSONObject("LineString");
        final JSONObject point = placemark.getJSONObject("Point");
        final JSONObject multiGeometry = placemark.getJSONObject("MultiGeometry");
        if ((point != null && Objects.equals(MapLayerTypeEnum.POINT.getValue(), loadType)) ||
                (lineString != null && Objects.equals(MapLayerTypeEnum.LINE.getValue(), loadType)) ||
                (multiGeometry != null && Objects.equals(MapLayerTypeEnum.POLYGON.getValue(), loadType))) {
            placemarkCount.incrementAndGet();
        }
    }

    @Override
    public ServiceRo loadXmlJson(JSONObject kmlObject, Integer folderId, Integer typeDefId, Boolean loadFolder, Integer mapLayerType, Integer projectId, Integer userId) {
        final JSONObject xml = kmlObject.getJSONObject("kml");
        final JSONObject document = xml.getJSONObject("Document");
        final JSONObject object = JSONObject.parseObject(document.toJSONString());
        final JSONObject result = kmlJsonLoadPrepare(kmlObject, mapLayerType);
        Integer placemarkCountTotal = result.getInteger("placemarkCountTotal");
        Constants.EXECUTOR.execute(() -> {
            log.info("Project[{}] - user[{}] loadObjs[{}] start...", projectId, userId, mapLayerType);
            AtomicInteger count = new AtomicInteger(0);
            final boolean isSaveFolder = loadFolder != null && loadFolder;
            recursionParserObj(object, isSaveFolder, folderId, projectId, userId, placemarkCountTotal, count, mapLayerType, typeDefId);
            log.info("Project[{}] - user[{}] loadObjs[{}] finished count[{}]", projectId, userId, mapLayerType, count);
        });
        return new ServiceRo().setData(result);
    }


    private void recursionParserObj(JSONObject object, boolean isSaveFolder, Integer parentId,
                                    Integer projectId, Integer userId, Integer placemarkCountTotal,
                                    AtomicInteger count, Integer loadType, Integer typeDefId) {
        final Set<Map.Entry<String, Object>> entries = object.entrySet();
        if (object.containsKey("Folder")) {
            final String folderName = object.getString("name");
            if (isSaveFolder) {
                final BasicInformation basicInformation = BasicInformation.builder()
                        .folder(true)
                        .name((folderName == null || "".equals(folderName)) ? "未命名Folder" : folderName)
                        .parentId(parentId)
                        .projectId(projectId)
                        .mapLayerType(loadType)
                        .build();
                basicInformationMapper.insert(basicInformation);
                parentId = basicInformation.getId();
                log.info("Save Folder[{}] - ID[{}]", folderName, parentId);
            }
        }
        for (Map.Entry<String, Object> entry : entries) {
            final String key = entry.getKey();
            final Object value = entry.getValue();
            if ("Folder".equals(key)) {
                if (value instanceof JSONArray) {
                    for (Object value2 : JSONArray.from(value)) {
                        recursionParserObj(JSONObject.from(value2), isSaveFolder, parentId, projectId, userId, placemarkCountTotal, count, loadType, typeDefId);
                    }
                    continue;
                }
                if (value instanceof JSONObject) {
                    recursionParserObj(JSONObject.from(value), isSaveFolder, parentId, projectId, userId, placemarkCountTotal, count, loadType, typeDefId);
                    continue;
                }
            }
            if ("Placemark".equals(key)) {
                if (value instanceof JSONArray) {
                    final String folderName = object.getString("name");
                    final BasicInformation basicInformation = BasicInformation.builder()
                            .folder(true)
                            .name((folderName == null || "".equals(folderName)) ? "未命名PlacemarkArray" : folderName)
                            .parentId(parentId)
                            .projectId(projectId)
                            .mapLayerType(loadType)
                            .build();
                    if (isSaveFolder) {
                        basicInformationMapper.insert(basicInformation);
                        log.info("Save Folder[{}] - ID[{}]", folderName, parentId);
                    }
                    final JSONArray placemarks = JSONArray.from(value);
                    for (Object placemark : placemarks) {
                        final JSONObject jsonObject = JSONObject.from(placemark);
                        dealPlacemark(jsonObject, isSaveFolder ? basicInformation.getId() : parentId, projectId, userId, placemarkCountTotal, count, loadType, typeDefId);
                    }
                } else {
                    dealPlacemark(JSONObject.from(value), parentId, projectId, userId, placemarkCountTotal, count, loadType, typeDefId);
                }
            }
        }
    }

    private void dealPlacemark(JSONObject placemark,
                               Integer parentId,
                               Integer projectId,
                               Integer userId,
                               Integer placemarkCountTotal,
                               AtomicInteger count,
                               Integer loadType,
                               Integer typeDefId) {
        final String name = placemark.getString("name");
        final String name0 = (name == null || "".equals(name)) ? "未命名Point" : name;
        final String description = placemark.getString("description");
        final JSONObject style = placemark.getJSONObject("Style");

        final JSONObject point = placemark.getJSONObject("Point");
        final JSONObject lineString = placemark.getJSONObject("LineString");
        final JSONObject multiGeometry = placemark.getJSONObject("MultiGeometry");

        int nameMaxLength = 50;
        int descriptionMaxLength = 2048;
        final boolean isValidName = !(name == null || "".equals(name) || name.length() >= nameMaxLength);
        final boolean isValidDesc = !(description == null || "".equals(description) || description.length() >= descriptionMaxLength);
        final Integer pointLayerType = MapLayerTypeEnum.POINT.getValue();
        final Integer lineLayerType = MapLayerTypeEnum.LINE.getValue();
        final Integer polygonLayerType = MapLayerTypeEnum.POLYGON.getValue();
        if (point != null && Objects.equals(pointLayerType, loadType)) {
            final Integer i = count.incrementAndGet();
            log.info(i + "-" + name + "-" + placemark.keySet());
            if (!isValidName && name != null && name.length() >= nameMaxLength) {
                log.error(name + " -> " + "名称文字过长[{}], 已丢弃", name.length());
            }
            if (!isValidDesc && description != null && description.length() >= descriptionMaxLength) {
                log.error(name + " -> " + "描述文字过长[{}], 已丢弃", description.length());
            }
            String coordinates = point.getString("coordinates");
            final String[] point1 = coordinates.split(",");
            final String lng = point1[0];
            final String lat = point1[1];
            final String alt = point1[2];
            final JSONObject point0 = JSONObject.of("lng", Double.valueOf(lng), "lat", Double.valueOf(lat), "alt", Float.valueOf(alt));
            final JSONObject jsonObject = JSONObject.of("position", point0);
            if (isValidDesc) {
                jsonObject.put("description", description);
            }
            jsonObject.put("name", name0);
            final BasicInformation basicInformation = BasicInformation.builder()
                    .folder(false)
                    .parentId(parentId)
                    .name(name0)
                    .typeDefId(typeDefId)
                    .mapLayerType(pointLayerType)
                    .jsonContent(jsonObject)
                    .projectId(projectId)
                    .build();
            basicInformationMapper.insert(basicInformation);
            webSocketService.sendUserKmlLoadMessage(JSONObject.from(WebSocketRo.builder().state(RoState.WEBSOCKET_SUCCESS.getValue())
                    .messageType(WebSocketMessageType.KML_LOAD_PROCESS.getValue())
                    .content(JSONObject.of("placemarkCountTotal", placemarkCountTotal,
                            "current", count.get(),
                            "percent", (count.get() * 100 / placemarkCountTotal))).build()), projectId, userId);
        }
        if (lineString != null && Objects.equals(lineLayerType, loadType)) {
            final Integer i = count.incrementAndGet();
            log.info(i + "-" + name + "-" + placemark.keySet());
            if (!isValidName && name != null && name.length() >= nameMaxLength) {
                log.error(name + " -> " + "名称文字过长[{}], 已丢弃", name.length());
            }
            if (!isValidDesc && description != null && description.length() >= descriptionMaxLength) {
                log.error(name + " -> " + "描述文字过长[{}], 已丢弃", description.length());
            }
            String coordinates = lineString.getString("coordinates");
            final ArrayList<JSONObject> linePoints = new ArrayList<>();
            coordinates = coordinates.replaceAll("\\n", " ");
            final String[] points = coordinates.split(" ");
            for (String point0 : points) {
                final String[] point1 = point0.split(",");
                final String lng = point1[0];
                final String lat = point1[1];
                final String alt = point1[2];
                linePoints.add(JSONObject.of("lng", Double.valueOf(lng), "lat", Double.valueOf(lat), "alt", Float.valueOf(alt)));
            }
            final JSONObject jsonObject = JSONObject.of(
                    "linePoints", linePoints
            );
            if (style != null) {
                final JSONObject styleObj = JSONObject.of();
                final JSONObject lineStyle = style.getJSONObject("LineStyle");
                if (lineStyle != null) {
                    final String color = lineStyle.getString("color");
                    final Integer width = lineStyle.getInteger("width");
                    if (color != null) {
                        styleObj.put("color", color.startsWith("#") ? color : "#" + color);
                    }
                    if (width != null) {
                        styleObj.put("width", width);
                    }
                }
                if (styleObj.size() > 0) {
                    jsonObject.put("lineStyle", styleObj);
                }
            }
            if (isValidDesc) {
                jsonObject.put("description", description);
            }
            jsonObject.put("name", name0);
            final BasicInformation basicInformation = BasicInformation.builder()
                    .folder(false)
                    .parentId(parentId)
                    .name(name0)
                    .typeDefId(typeDefId)
                    .mapLayerType(lineLayerType)
                    .jsonContent(jsonObject)
                    .projectId(projectId)
                    .build();
            basicInformationMapper.insert(basicInformation);
            webSocketService.sendUserKmlLoadMessage(JSONObject.from(WebSocketRo.builder().state(RoState.WEBSOCKET_SUCCESS.getValue())
                    .messageType(WebSocketMessageType.KML_LOAD_PROCESS.getValue())
                    .content(JSONObject.of("placemarkCountTotal", placemarkCountTotal,
                            "current", count.get(),
                            "percent", (count.get() * 100 / placemarkCountTotal))).build()), projectId, userId);
        }

        if (multiGeometry != null && Objects.equals(polygonLayerType, loadType)) {
            final Integer i = count.incrementAndGet();
            log.info(i + "-" + name + "-" + placemark.keySet());
            if (!isValidName && name != null && name.length() >= nameMaxLength) {
                log.error(name + " -> " + "名称文字过长[{}], 已丢弃", name.length());
            }
            if (!isValidDesc && description != null && description.length() >= descriptionMaxLength) {
                log.error(name + " -> " + "描述文字过长[{}], 已丢弃", description.length());
            }
            JSONObject geometryLineString = multiGeometry.getJSONObject("LineString");
            String coordinates = geometryLineString.getString("coordinates");
            final ArrayList<JSONObject> linePoints = new ArrayList<>();
            coordinates = coordinates.replaceAll("\\n", " ");
            final String[] points = coordinates.split(" ");
            for (String point0 : points) {
                final String[] point1 = point0.split(",");
                final String lng = point1[0];
                final String lat = point1[1];
                final String alt = point1[2];
                linePoints.add(JSONObject.of("lng", Double.valueOf(lng), "lat", Double.valueOf(lat), "alt", Float.valueOf(alt)));
            }
            final JSONObject jsonObject = JSONObject.of(
                    "polygonPoints", linePoints
            );
            if (style != null) {
                final JSONObject styleObj = JSONObject.of();
                final JSONObject lineStyle = style.getJSONObject("LineStyle");
                if (lineStyle != null) {
                    final String color = lineStyle.getString("color");
                    final Integer width = lineStyle.getInteger("width");
                    if (color != null) {
                        styleObj.put("lineColor", color.startsWith("#") ? color : "#" + color);
                    }
                    if (width != null) {
                        styleObj.put("lineWidth", width);
                    }
                }
                if (styleObj.size() > 0) {
                    jsonObject.put("polygonStyle", styleObj);
                }
            }
            if (isValidDesc) {
                jsonObject.put("description", description);
            }
            jsonObject.put("name", name0);
            final BasicInformation basicInformation = BasicInformation.builder()
                    .folder(false)
                    .parentId(parentId)
                    .name(name0)
                    .typeDefId(typeDefId)
                    .mapLayerType(polygonLayerType)
                    .jsonContent(jsonObject)
                    .projectId(projectId)
                    .build();
            basicInformationMapper.insert(basicInformation);
            webSocketService.sendUserKmlLoadMessage(JSONObject.from(WebSocketRo.builder().state(RoState.WEBSOCKET_SUCCESS.getValue())
                    .messageType(WebSocketMessageType.KML_LOAD_PROCESS.getValue())
                    .content(JSONObject.of("placemarkCountTotal", placemarkCountTotal,
                            "current", count.get(),
                            "percent", (count.get() * 100 / placemarkCountTotal))).build()), projectId, userId);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    public ServiceRo batchDelete(List<Integer> ids, Integer projectId) {
        log.info(ids.toString());
        final List<BasicInformation> basicInformationList = basicInformationMapper.selectBatchIds(ids);
        final ArrayList<Integer> readyForDelete = new ArrayList<>();
        for (BasicInformation basicInformation : basicInformationList) {
            if (Objects.equals(basicInformation.getProjectId(), projectId)) {
                readyForDelete.add(basicInformation.getId());
            }
        }
        if (readyForDelete.size() == 0){
            return new ServiceRo().setData(JSONObject.of("count", 0));
        }
        return new ServiceRo().setData(JSONObject.of("count", basicInformationMapper.deleteBatchIds(readyForDelete)));
    }

    /**
     * 通过ID删除一条数据
     *
     * @return 是否操作成功
     */
    @Override
    public ServiceRo deleteById(Integer id, Integer projectId) {
        if (Objects.nonNull(id)) {
            BasicInformation basicInformation = basicInformationMapper.selectById(id);
            if (Objects.nonNull(basicInformation)) {
                final Integer typeDefId = basicInformation.getTypeDefId();
                System.out.println(typeDefId);
                final SysTypeDef sysTypeDef = sysTypeDefService.selectById(typeDefId);
//                final JSONObject jsonObject = JSONObject.from(sysTypeDef.getOtherParam());
//                if (jsonObject != null) {
//                    final Integer mapLayerType = jsonObject.getInteger("mapLayerType");
//                }
                Constants.EXECUTOR.execute(() -> {
                    if (basicInformation.getFolder()) {
                        deleteChildren(basicInformation.getId(), projectId);
                    }
                    log.info("delete basicInformation[{}]", basicInformation.getId());
                });
                if (1 == basicInformationMapper.deleteById(id)) {
                    return new ServiceRo();
                }
            } else {
                return new ServiceRo().setResult(false).setMessage("未查询到[id]");
            }
            return new ServiceRo();
        }
        return new ServiceRo().setResult(false).setMessage("参数[id]异常");
    }


    private void deleteChildren(Integer parentId, Integer projectId) {
        final List<BasicInformation> children = basicInformationMapper.selectList(Wrappers.<BasicInformation>lambdaQuery()
                .eq(BasicInformation::getParentId, parentId)
                .eq(BasicInformation::getProjectId, projectId));
        for (BasicInformation child : children) {
            final Integer id = child.getId();
            if (child.getFolder()) {
                deleteChildren(id, projectId);
                basicInformationMapper.deleteById(id);
            } else {
                basicInformationMapper.deleteById(id);
            }
            log.info("delete basicInformation[{}]", id);
        }
    }


    /**
     * 通过ID更新一条数据
     *
     * @param operateMo 实体对象参数集
     * @return 是否操作成功
     */
    @Override
    public boolean update(OperateMo operateMo) {
        ObjectMapper objectMapper = new ObjectMapper();
        BasicInformation basicInformation = objectMapper.convertValue(operateMo.getEntity(), BasicInformation.class);
        return 1 == basicInformationMapper.update(basicInformation, new QueryWrapper<BasicInformation>().allEq(operateMo.getEqMap()));
    }
}
